package com.tcs.test.executor.forkjoin;

import java.util.ArrayList;
import java.util.concurrent.RecursiveTask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * https://www.liaoxuefeng.com/article/001493522711597674607c7f4f346628a76145477e2ff82000
 * 
* @Title: SumTask.java
* @Package com.tcs.test.executor.forkjoin
* @author 神经刀
* @date 2018年9月15日
* @version V1.0
 */
class SumTask extends RecursiveTask<Long> {
	
	private static final long serialVersionUID = 1L;

	private final Logger logger = LoggerFactory.getLogger(SumTask.class);

	static final int THRESHOLD = 10000000;
	long[] array;
	int start;
	int end;

	SumTask(long[] array, int start, int end) {
		this.array = array;
		this.start = start;
		this.end = end;
	}

	@Override
	protected Long compute() {
		if (end - start <= THRESHOLD) {
			// 如果任务足够小,直接计算:
			long sum = 0;
			for (int i = start; i < end; i++) {
				sum += array[i];
			}
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
			}
			logger.info(" compute : start:{} , end:{}, sum:{}" ,  start, end, sum);
			return sum;
		}
		// 任务太大,一分为二:
		int middle = (end + start) / 2;
		logger.info("start : {} ~ end : {} , start: {} ~ middle : {} , middle : {} ~ end : {}" , start, end, start, middle, middle, end);
		SumTask subtask1 = new SumTask(this.array, start, middle);
		SumTask subtask2 = new SumTask(this.array, middle, end);
		invokeAll(subtask1, subtask2);
		Long subresult1 = subtask1.join();
		Long subresult2 = subtask2.join();
		Long result = subresult1 + subresult2;
		logger.info("subresult1 : {} , subresult2 : {} , result {}" , subresult1 , subresult2 , result);
		return result;
	}
}